import { Application } from "../Application";
import { logger } from "../util/logger";
import { miscCfg, RpcMsg, RpcMsgId, SvrInfo } from "../util/defines";
import { RpcSocket } from "./RpcSocket";
import { TcpServer } from "../tcp/TcpServer";
import { TcpSocket } from "../tcp/TcpSocket";
import { TcpUnregedSocket } from "../tcp/TcpUnregedSocket";

/**
 * RPC服务端
 */
export class RpcServer {

    app: Application;
    svr: TcpServer;

    constructor(app: Application, onStart: () => void) {
        this.app = app;
        this.svr = new TcpServer(app.svr.port, onStart, this.onScoket.bind(this));
    }

    private onScoket(socket: TcpSocket) {
        new TcpUnregedSocket(this.app, socket, this.onSocketReg.bind(this));
    }

    private onSocketReg(socket: TcpSocket, svr: SvrInfo) {
        if (svr) {
            new RpcSvrSocket(this.app, socket, svr);
        } else {
            logger.error(`${socket.remoteAddress}非法注册,Rpc服务端只接受服务器连接的注册`, this, this.onSocketReg);
            socket.close();
        }
    }

}

/**
 * RPC服务端Socket
 */
class RpcSvrSocket extends RpcSocket {

    private _hbTimeoutTimer: NodeJS.Timeout;

    constructor(app: Application, socket: TcpSocket, remoteSvr: SvrInfo) {
        super(app, remoteSvr);
        if(this.onReg(socket)){
            this.send(RpcMsgId.regOk);
            this._hbTimeoutTimer = setTimeout(this.onHeartbeatTimeout.bind(this), miscCfg.heartbeatTime + miscCfg.heartbeatTimeout);
            this.app.rpcService.runWaitConnCbs(this.remoteSvr.id, null, this);
        }
    }

    protected onMsg(data: { msgId: RpcMsgId, msg: RpcMsg }) {
        switch (data.msgId) {
            case RpcMsgId.heartbeat:
                this._hbTimeoutTimer.refresh();
                this.send(RpcMsgId.heartbeat);
                break;
        }
    }

    protected onClose() {
        clearTimeout(this._hbTimeoutTimer);
    }

    private onHeartbeatTimeout() {
        logger.error(`${this.remoteSvr.id}心跳包超时,已断开连接`, this, this.onHeartbeatTimeout);
        this.close();
    }
}